import Image, ImageDraw, ImageFont, time
from OpenGL.GL import *

class font:
    def __init__(self):
        t = time.time()
        print "Generating Fonts",
        ## Init the image and font to use
        isize = (128,128)
        image = Image.new('RGBA',isize)
        draw = ImageDraw.Draw(image)
        font = ImageFont.truetype("georgia.ttf", 14)

        ## map the keys into an array
        keyboard = [
            'A','a','B','b','C','c','D','d','E','e','F','f','G','g',
            'H','h','I','i','J','j','K','k','L','l','M','m','N','n',
            'O','o','P','p','Q','q','R','r','S','s','T','t','U','u',
            'V','v','W','w','X','x','Y','y','Z','z','1','2','3','4',
            '5','6','7','8','9','0','`','~','!','@','#','$','%','^',
            '&','*','(',')','-','_','=','+','[','{',']','}','\\','|',
            ';',':','\'','"',',','<','.','>','/','?',' '
            ]
        mapping = {}
        cwidth = 0
        cheight = 0


        for i,key in enumerate(keyboard):
            size = font.getsize(key)
            
            ## Get the size of the next key to test for font-wrapping
            if i+1 < len(keyboard):
                nsize = font.getsize(keyboard[i+1])
            else:
                nsize = (0,0)
                
            ## Assign the size and orgin of the key for uv-mapping
            mapping[key] = ((cwidth,cheight),(cwidth+size[0],cheight+size[1]))
            
            ## Draw the key on the image
            draw.text((cwidth, cheight), key, font=font)
            
            ## Assign the next letter's origin & check for font-wrapping
            if cwidth + size[0] + nsize[0] >= isize[0]:
                cwidth = 0
                cheight += size[1]
            else:
                cwidth += size[0]
                
        
        image = image.tostring("raw", "RGBA", 0, -1)
        fList = glGenTextures(1)

        ## Bind texture into memory
        (w,h)  = isize
        self.texture = glGenTextures(1)
        glBindTexture(GL_TEXTURE_2D, self.texture)
        glPixelStorei(GL_UNPACK_ALIGNMENT,1)
        glTexImage2D(GL_TEXTURE_2D, 0, 3, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE,  image)
        self.font = {}
        self.keys = mapping

        ## Generate a plane for each letter
        for i,key in enumerate(mapping.keys()):
            ## Init the display list for OpenGL
            display_list = glGenLists(1)
            self.font[key] = display_list
            ## Setup Display List
            glNewList(display_list,GL_COMPILE) 
            
            ## Get key's width and height
            (origin,size) = mapping[key]
            key_size = size[0]-origin[0], size[1]-origin[1]
            
            ## Draw the rectangle and uv for the key
            glBegin(GL_QUADS) 
            glTexCoord2f( float(origin[0])/isize[0], 1.0-(float(size[1])/isize[1])    ); glVertex2i( 0          , 0           )
            glTexCoord2f( float(size[0])/isize[0],   1.0-(float(size[1])/isize[1])    ); glVertex2i( key_size[0], 0           )
            glTexCoord2f( float(size[0])/isize[0],   1.0-(float(origin[1])/isize[1])  ); glVertex2i( key_size[0], key_size[1] )
            glTexCoord2f( float(origin[0])/isize[0], 1.0-(float(origin[1])/isize[1])  ); glVertex2i( 0          , key_size[1] )
            
            glEnd()
            glEndList()
        print "\nFonts Loaded: %s secs"%(time.time()-t)
        
    def render(self,string,screen_coords=(0,0)):
        ( x, y ) = screen_coords

        glEnable   ( GL_ALPHA_TEST )
        glEnable   ( GL_BLEND      )
        glDisable  ( GL_DEPTH_TEST )
        glDepthFunc( GL_LEQUAL     )		
        
        glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA )
        
        glAlphaFunc( GL_GREATER, 0.1 )
        
        glEnable(GL_TEXTURE_2D) ## Enable Texture Mapping
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
        glBindTexture(GL_TEXTURE_2D, self.texture)
        
        
        glEnable(GL_CULL_FACE) ## Only draw one-sided
        
        glColor4f(1.0,1.0,1.0,1.0)
        for char in string:		
            (origin,size) = self.keys[char]
            char_size = size[0]-origin[0], size[1]-origin[1]
            
            glPushMatrix()
            glTranslatef( x, y, 0 )
            #glRotatef(mesh.rotation[0], 1.0,  0  ,   0)
            #glRotatef(mesh.rotation[1], 0  ,  1.0,   0)
            #glRotatef(mesh.rotation[2], 0  ,  0  , 1.0)
            #glScalef(2.0, 2.0, 2.0)
            glCallList( self.font[char] )
            glPopMatrix()
            
            x += char_size[0]
            
        glDisable( GL_CULL_FACE  )
        glDisable( GL_TEXTURE_2D )
        glDisable( GL_BLEND      )	
        glDisable( GL_ALPHA_TEST )
        
        glEnable ( GL_DEPTH_TEST )